package jmine.tec.web.front.dispatcher.request;

import java.io.IOException;
import java.text.ParseException;

import jmine.tec.extensions.forms.FormHandler;
import jmine.tec.rpc.common.serialization.Serializer;
import jmine.tec.web.front.FrontException;
import jmine.tec.web.front.FrontMessages;
import jmine.tec.web.front.domain.BackOfficeRequest;
import jmine.tec.web.front.forms.FormMetadataRegistry;

/**
 * Sends a request to the back office
 * 
 * @author lundberg
 */
public class RegistryBasedBackOfficeRequestSender implements BackOfficeRequestSender {

    private final FormMetadataRegistry formMetadataRegistry;

    private final Serializer serializer;

    /**
     * Constructor
     * 
     * @param formMetadataRegistry formMetadataRegistry
     * @param serializer serializer
     */
    public RegistryBasedBackOfficeRequestSender(FormMetadataRegistry formMetadataRegistry, Serializer serializer) {
        super();
        this.formMetadataRegistry = formMetadataRegistry;
        this.serializer = serializer;
    }

    /**
     * Sends a request to the back office
     * 
     * @param request request
     */
    @SuppressWarnings("unchecked")
    public void send(BackOfficeRequest request) {
        Object form = this.deserializeForm(request);
        this.findFormHandlerFor(form).apply(form);
    }

    /**
     * Finds a suitable handler for the given form
     * 
     * @param form form
     * @return handler
     */
    private FormHandler findFormHandlerFor(Object form) {
        return this.formMetadataRegistry.find(form).getFormHandler();
    }

    /**
     * Deserializes the given form
     * 
     * @param request request
     * @return object
     */
    private Object deserializeForm(BackOfficeRequest request) {
        try {
            return this.serializer.deserialize(request.getFormContent());
        } catch (IOException e) {
            throw new FrontException(FrontMessages.IO_EXCEPTION_DESERIALIZING_FORM.create(), e);
        } catch (ParseException e) {
            throw new FrontException(FrontMessages.PARSE_EXCEPTION_DESERIALIZING_FORM.create(), e);
        }
    }
}
